package mbean;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.faces.model.SelectItem;

import org.richfaces.model.selection.SimpleSelection;

import util.FacesUtil;
import vo.OrganizationVO;
import vo.OrganizationValueVO;
import vo.UsuarioVO;
import dao.OrganizationDAO;
import dao.UsuarioDAO;

public class OrganizationMBean extends AbstractMBean{
	
	private List<OrganizationVO> listOrganization;
	private OrganizationVO detailOrganization;
	private String nome, missao, visao, newValue;
	private List<SelectItem> listUsers;
	private int admin, valorSelecionado, id, back;
	private List<OrganizationValueVO> listValues, listValuesDeletado;
	private OrganizationDAO dao;
	private boolean createNewValue, menuSaveDisabled, valueChanged;
	private SimpleSelection selection;
	
	public OrganizationMBean(){
		dao = new OrganizationDAO();
		this.listValuesDeletado = new ArrayList<OrganizationValueVO>();
		listOrganization = dao.listOrganization();
		this.menuSaveDisabled = true;
		valueChanged = false;
	}

	public String searchOrganization(){			
		listOrganization = dao.listOrganization();
		this.menuSaveDisabled = true;
		setaTela(false, "organization");
		
		return "organization";
	}

	public void setListOrganization(List<OrganizationVO> listOrganization) {
		this.listOrganization = listOrganization;
	}

	public List<OrganizationVO> getListOrganization() {
		return listOrganization;
	}

	public void setDetailOrganization(OrganizationVO detailOrganization) {
		this.detailOrganization = detailOrganization;
	}

	public OrganizationVO getDetailOrganization() {
		return detailOrganization;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public String getNome() {
		return nome;
	}

	public void setMissao(String missao) {
		this.missao = missao;
	}

	public String getMissao() {
		return missao;
	}

	public void setVisao(String visao) {
		this.visao = visao;
	}

	public String getVisao() {
		return visao;
	}

	public void setListUsers(List<SelectItem> listUsers) {
		this.listUsers = listUsers;
	}

	public List<SelectItem> getListUsers() {
		return listUsers;
	}

	public void setAdmin(int admin) {
		this.admin = admin;
	}

	public int getAdmin() {
		return admin;
	}
	
	public String preparaTelaInsercao(){
		populaComboUsuario();
		
		this.visao = "";
		this.missao = "";
		this.nome = "";
		this.id = 0;
		this.listValues = new ArrayList<OrganizationValueVO>();
		this.listValuesDeletado = new ArrayList<OrganizationValueVO>();
		this.menuSaveDisabled = false;
		
		setaTela(true, "organization");
		
		return "insert";
	}
	
	private void populaComboUsuario(){
		SelectItem si;
		
		UsuarioDAO usuarioDAO = new UsuarioDAO();
		List<UsuarioVO> listaUsuarioVO = usuarioDAO.searchUser(new UsuarioVO());
		listUsers = new ArrayList<SelectItem>();
		
		si = new SelectItem();
		si.setLabel("");
		si.setValue("");
		listUsers.add(si);
		
		for(UsuarioVO vo:listaUsuarioVO){
			si = new SelectItem();
			si.setLabel(vo.getNome());
			si.setValue(vo.getId());
			listUsers.add(si);
		}		
	}
	
	public String preparaTelaEdicao(){
		populaComboUsuario();
		setaTela(true, "organization");
		valueChanged = false;
		
		return "edit";
	}
	
	public String save(){
		OrganizationVO vo = new OrganizationVO();
		
		if (this.id > 0)
			vo.setId(this.id);
		else
			vo.setId(-1);
		
		vo.setIdAdmin(this.admin);
		vo.setListaValoresOrganizacao(this.listValues);
		vo.setMissao(this.missao);
		vo.setNome(this.nome);
		vo.setVisao(this.visao);
		dao.saveOrganization(vo, this.listValuesDeletado);		

		searchOrganization();
		
		if (FacesUtil.getSessionMapValue("menu") != null){
			MenuMBean mmb = (MenuMBean) FacesUtil.getSessionMapValue("menu");
			mmb.loadTree();
		}
	
		return "save";
	}

	public void setListValues(List<OrganizationValueVO> listValues) {
		this.listValues = listValues;
	}

	public List<OrganizationValueVO> getListValues() {
		return listValues;
	}
	
	public void setNewValue(String newValue) {
		this.newValue = newValue;
	}

	public String getNewValue() {
		return newValue;
	}
	
	public String insertNewValue(){
		if (this.newValue.equalsIgnoreCase("")){
			FacesUtil.addErrorMessage(FacesUtil.getMessageResourceString("errorNewValueRequired"));
		}
		else{
			OrganizationValueVO vo = new OrganizationValueVO(); 
			vo.setValue(this.newValue);
			vo.setId(-1);
			
			int position;
			if (this.listValues.size() > 0)
				position = this.listValues.get(this.listValues.size() - 1).getPosition();
			else
				position = 0;
			
			position++;
			vo.setPosition(position);
			
			this.listValues.add(vo);
			this.newValue = "";
			this.createNewValue = false;
			this.valueChanged = true;
		}
		
		return "";
	}
	
	public String deleteValue(){
		OrganizationValueVO ov = this.listValues.get(this.valorSelecionado);
		this.listValues.remove(ov);
		this.listValuesDeletado.add(ov);
		
		this.selection.removeKey(this.valorSelecionado);
		int ordem = 1;
		for(OrganizationValueVO vo: this.listValues){
			vo.setPosition(ordem);
			ordem++;
		}
		
		this.valueChanged = true;
		
		return "defineValues";
	}

	public void setValorSelecionado(int valorSelecionado) {
		this.valorSelecionado = valorSelecionado;
	}

	public int getValorSelecionado() {
		return valorSelecionado;
	}
	
	public void setId(int id) {
		this.id = id;
	}

	public int getId() {
		return id;
	}
	
	public String redirecionaBack(){
		if (this.back == 0){
			setaTela(true, "strategy");
			return "back";
		}
		else{
			setaTela(false, null);
			return "backIndex";
		}
	}

	public void setBack(int back) {
		this.back = back;
	}

	public int getBack() {
		return back;
	}

	public void open() {
		StrategyMBean smb = (StrategyMBean) FacesUtil.getSessionMapValue("strategy");		
		OrganizationVO vo = dao.getOrganization(smb.getSelectedOrganization());
		
		this.missao = vo.getMissao();
		this.nome = vo.getNome();
		this.visao = vo.getVisao();
		this.admin = vo.getIdAdmin();
		this.listValues = vo.getListaValoresOrganizacao();
		this.id = vo.getId();
		this.createNewValue = false;
		this.valueChanged = false;
		
		setaTela(true, "organization");
	}

	public void setCreateNewValue(boolean createNewValue) {
		this.createNewValue = createNewValue;
	}

	public boolean getCreateNewValue() {
		return createNewValue;
	}
	
	public void prepareInsertNewValue(){
		this.createNewValue = true;
	}
	
	public String upValue(){
		if ((this.selection != null) && (this.selection.getKeys().hasNext())){
			int linha = (Integer) this.selection.getKeys().next();
			this.selection.removeKey(linha);
			
			if (linha > 0){
				OrganizationValueVO voSel = this.listValues.get(linha);
				voSel.setPosition(voSel.getPosition() - 1);
				
				voSel = this.listValues.get(linha - 1);
				voSel.setPosition(voSel.getPosition() + 1);
			}
			
			orderValues();
			this.valueChanged = true;
		}
		
		return "defineValues";
	}
	
	public String downValue(){
		if ((this.selection != null) && (this.selection.getKeys().hasNext())){
			int linha = (Integer) this.selection.getKeys().next();
			this.selection.removeKey(linha);
			
			if (linha < this.listValues.size() - 1){
				OrganizationValueVO voSel = this.listValues.get(linha);
				voSel.setPosition(voSel.getPosition() + 1);
				
				voSel = this.listValues.get(linha + 1);
				voSel.setPosition(voSel.getPosition() - 1);
			}
			
			orderValues();
			this.valueChanged = true;
		}	
		
		return "defineValues";
	}
	
	@SuppressWarnings("unchecked")
	private void orderValues(){
		Collections.sort(this.listValues, new Comparator(){
			public int compare(Object obj0, Object obj1) {
				OrganizationValueVO o0 = (OrganizationValueVO) obj0;
				OrganizationValueVO o1 = (OrganizationValueVO) obj1;
				
				if (o0.getPosition() > o1.getPosition())
					return 1;
				else if (o0.getPosition() == o1.getPosition())
					return 0;
				else
					return -1;
			}
		});		
	}

	public void setSelection(SimpleSelection selection) {
		this.selection = selection;
	}

	public SimpleSelection getSelection() {
		return selection;
	}

	public void setMenuSaveDisabled(boolean menuSaveDisabled) {
		this.menuSaveDisabled = menuSaveDisabled;
	}

	public boolean getMenuSaveDisabled() {
		return menuSaveDisabled;
	}
	
	public String back(){
		this.menuSaveDisabled = true;
		setaTela(false, "organization");
		return "back";
	}

	@Override
	public boolean isDirty() {
		boolean dirty = false;
		
		if (this.id > 0){
			OrganizationVO vo = this.dao.getOrganization(id);
			
			if (! vo.getNome().equalsIgnoreCase(this.nome))
				dirty = true;
			
			if (! vo.getMissao().equalsIgnoreCase(this.missao))
				dirty = true;
			
			if (! vo.getVisao().equalsIgnoreCase(this.visao))
				dirty = true;
			
			if (vo.getIdAdmin() != this.admin)
				dirty = true;
			
			if (this.valueChanged)
				dirty = true;
		}
		else
			dirty = true;
		
		return dirty;
	}
}